import http from "@/api/axios";
import {Request} from "@/api/Request";
import Utils from "@/common/utils/Utils";

export class BaseApi<T> {
    API_PREFIX!: string;

    /**
     * 根据条件获取单条数据
     */
    public getOne(t: T) {
        return new Request<Result<T>>().setHttp(() => http.get(this.getUrl('one'), {params: t}));
    }

    /**
     * 根据条件获取多条数据
     */
    public getList(t?: T) {
        return new Request<Result<T[]>>().setHttp(() => http.get(this.getUrl('list'), {params: t}))
    }

    /**
     * 根据条件获取分页数据
     * @param size
     * @param current
     * @param orders 排序字段, eg: ['sort','name desc']
     * @param t
     */
    public getPage(page: Page<any>, t: T) {
        const orders: string[] = [];
        if (!page.orders) {
            page.orders = [];
        }
        //对排序字段手动序列化
        for (const orderItem of page.orders) {
            if (orderItem.asc == false) {
                orders.push(Utils.format(orderItem.column + ' desc'))
            } else {
                orders.push(orderItem.column)
            }
        }
        const request = new Request<Result<Page<T>>>();
        request.setHttp(() => {
            return http.get(this.getUrl('page'), {params: {size: page.size, current: page.current, orders: orders.toString(), ...t}});
        })
        return request;
    }

    /**
     * 根据ID获取单条数据
     * @param id
     */
    public getById(id: string) {
        return new Request<Result<T>>().setHttp(() => http.get(this.getUrl(id)))
    }

    /**
     * 新增单条数据
     */
    public create(t: T) {
        return new Request<Result<any>>().setHttp(() => http.post(this.getUrl(), t));
    }

    /**
     * 修改单条数据
     * @param t
     */
    public update(t: T) {
        return new Request<Result<any>>().setHttp(() => http.put(this.getUrl(), t))
    }

    /**
     * 根据ID删除单条数据
     * @param id
     */
    public deleteById(id: string) {
        return new Request<Result<any>>().setHttp(() => http.delete(this.getUrl(id)))
    }

    /**
     * 修改或者新增单条数据
     * @param t
     */
    public saveOrUpdate(t: T) {
        return new Request<Result<T>>().setHttp(() => http.put(this.getUrl('saveOrUpdate'), t))
    }

    /**
     * 修改或者新增多条数据
     * @param list
     */
    public saveOrUpdateBatch(list: T[]) {
        return new Request<Result<any>>().setHttp(() => http.put(this.getUrl('saveOrUpdateBatch'), list))
    }

    /**
     * 根据ID修改多条数据
     * @param list
     */
    public updateBatchById(list: T[]) {
        const request = new Request<Result<any>>();
        request.setHttp(() => {
            return http.put(this.getUrl('updateBatchById'), list);
        })
        return request;
    }

    /**
     * 根据条件修改多条数据
     * @param record
     * @param condition
     */
    public updateBatch(record: T, condition: T) {
        const request = new Request<Result<any>>();
        request.setHttp(() => {
            return http.put(this.getUrl('updateBatch'), null, {data: record, params: condition});
        })
        return request;
    }

    /**
     * ping 接口连通性
     */
    public ping() {
        const request = new Request<Result<any>>();
        request.setHttp(() => {
            return http.get(this.getUrl('ping'));
        })
        return request;
    }

    public getUrl(request?: string): string {
        return getApiUrl(this.API_PREFIX, request);
    }
}


export function getApiUrl(API_PREFIX: string, request?: string) {
    if (request) {
        return '/' + process.env.PROJECT_API_PREFIX + '/' + API_PREFIX + '/' + request;
    } else {
        return '/' + process.env.PROJECT_API_PREFIX + '/' + API_PREFIX;
    }
}

export default new BaseApi();

export interface Page<T> {
    size?: number;
    current?: number;
    records?: T[];
    orders?: OrderItem[];
    total?: number;
    loading?: boolean;
}

export interface Result<T> {
    code?: number;
    success?: boolean;
    msg?: string;
    data?: T;
}

export interface BaseEntity {
    createUserId?: number;
    createTime?: Date;
    updateUserId?: number;
    updateTime?: Date;
}

export interface OrderItem {
    column: string;
    asc?: boolean;
}